<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>Module: ActiveRecord::Transactions::ClassMethods</title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
  <script type="text/javascript">
  // <![CDATA[

  function popupCode( url ) {
    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }

  function toggleCode( id ) {
    if ( document.getElementById )
      elem = document.getElementById( id );
    else if ( document.all )
      elem = eval( "document.all." + id );
    else
      return false;

    elemStyle = elem.style;
    
    if ( elemStyle.display != "block" ) {
      elemStyle.display = "block"
    } else {
      elemStyle.display = "none"
    }

    return true;
  }
  
  // Make codeblocks hidden by default
  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
  
  // ]]>
  </script>

</head>
<body>



    <div id="classHeader">
        <table class="header-table">
        <tr class="top-aligned-row">
          <td><strong>Module</strong></td>
          <td class="class-name-in-header">ActiveRecord::Transactions::ClassMethods</td>
        </tr>
        <tr class="top-aligned-row">
            <td><strong>In:</strong></td>
            <td>
                <a href="../../../files/vendor/rails/activerecord/lib/active_record/transactions_rb.html">
                vendor/rails/activerecord/lib/active_record/transactions.rb
                </a>
        <br />
            </td>
        </tr>

        </table>
    </div>
  <!-- banner header -->

  <div id="bodyContent">



  <div id="contextContent">

    <div id="description">
      <p>
<a href="../Transactions.html">Transactions</a> are protective blocks where
SQL statements are only permanent if they can all succeed as one atomic
action. The classic example is a transfer between two accounts where you
can only have a deposit if the withdrawal succeeded and vice versa. <a
href="../Transactions.html">Transactions</a> enforce the integrity of the
database and guard the data against program errors or database break-downs.
So basically you should use <a
href="ClassMethods.html#M001340">transaction</a> blocks whenever you have a
number of statements that must be executed together or not at all. Example:
</p>
<pre>
  ActiveRecord::Base.transaction do
    david.withdrawal(100)
    mary.deposit(100)
  end
</pre>
<p>
This example will only take money from David and give to Mary if neither
<tt>withdrawal</tt> nor <tt>deposit</tt> raises an exception. Exceptions
will force a ROLLBACK that returns the database to the state before the <a
href="ClassMethods.html#M001340">transaction</a> was begun. Be aware,
though, that the objects will <em>not</em> have their instance data
returned to their pre-transactional state.
</p>
<h2>Different Active Record classes in a single <a href="ClassMethods.html#M001340">transaction</a></h2>
<p>
Though the <a href="ClassMethods.html#M001340">transaction</a> class method
is called on some Active Record class, the objects within the <a
href="ClassMethods.html#M001340">transaction</a> block need not all be
instances of that class. This is because transactions are per-database
connection, not per-model.
</p>
<p>
In this example a <tt>Balance</tt> record is transactionally saved even
though <tt><a href="ClassMethods.html#M001340">transaction</a></tt> is
called on the <tt>Account</tt> class:
</p>
<pre>
  Account.transaction do
    balance.save!
    account.save!
  end
</pre>
<p>
Note that the <tt><a href="ClassMethods.html#M001340">transaction</a></tt>
method is also available as a model instance method. For example, you can
also do this:
</p>
<pre>
  balance.transaction do
    balance.save!
    account.save!
  end
</pre>
<h2><a href="../Transactions.html">Transactions</a> are not distributed across database connections</h2>
<p>
A <a href="ClassMethods.html#M001340">transaction</a> acts on a single
database connection. If you have multiple class-specific databases, the <a
href="ClassMethods.html#M001340">transaction</a> will not protect
interaction among them. One workaround is to begin a <a
href="ClassMethods.html#M001340">transaction</a> on each class whose models
you alter:
</p>
<pre>
  Student.transaction do
    Course.transaction do
      course.enroll(student)
      student.units += course.units
    end
  end
</pre>
<p>
This is a poor solution, but full distributed transactions are beyond the
scope of Active Record.
</p>
<h2>Save and destroy are automatically wrapped in a <a href="ClassMethods.html#M001340">transaction</a></h2>
<p>
Both <a href="../Base.html#M001739">Base#save</a> and <a
href="../Base.html#M001683">Base#destroy</a> come wrapped in a <a
href="ClassMethods.html#M001340">transaction</a> that ensures that whatever
you do in validations or callbacks will happen under the protected cover of
a <a href="ClassMethods.html#M001340">transaction</a>. So you can use
validations to check for values that the <a
href="ClassMethods.html#M001340">transaction</a> depends on or you can
raise exceptions in the callbacks to rollback, including <tt>after_*</tt>
callbacks.
</p>
<h2>Exception handling and rolling back</h2>
<p>
Also have in mind that exceptions thrown within a <a
href="ClassMethods.html#M001340">transaction</a> block will be propagated
(after triggering the ROLLBACK), so you should be ready to catch those in
your application code.
</p>
<p>
One exception is the <a href="../Rollback.html">ActiveRecord::Rollback</a>
exception, which will trigger a ROLLBACK when raised, but not be re-raised
by the <a href="ClassMethods.html#M001340">transaction</a> block.
</p>
<p>
<b>Warning</b>: one should not catch <a
href="../StatementInvalid.html">ActiveRecord::StatementInvalid</a>
exceptions inside a <a href="ClassMethods.html#M001340">transaction</a>
block. <a href="../StatementInvalid.html">StatementInvalid</a> exceptions
indicate that an error occurred at the database level, for example when a
unique constraint is violated. On some database systems, such as
PostgreSQL, database errors inside a <a
href="ClassMethods.html#M001340">transaction</a> causes the entire <a
href="ClassMethods.html#M001340">transaction</a> to become unusable until
it&#8216;s restarted from the beginning. Here is an example which
demonstrates the problem:
</p>
<pre>
  # Suppose that we have a Number model with a unique column called 'i'.
  Number.transaction do
    Number.create(:i =&gt; 0)
    begin
      # This will raise a unique constraint error...
      Number.create(:i =&gt; 0)
    rescue ActiveRecord::StatementInvalid
      # ...which we ignore.
    end

    # On PostgreSQL, the transaction is now unusable. The following
    # statement will cause a PostgreSQL error, even though the unique
    # constraint is no longer violated:
    Number.create(:i =&gt; 1)
    # =&gt; &quot;PGError: ERROR:  current transaction is aborted, commands
    #     ignored until end of transaction block&quot;
  end
</pre>
<p>
One should restart the entire <a
href="ClassMethods.html#M001340">transaction</a> if a StatementError
occurred.
</p>

    </div>


   </div>

    <div id="method-list">
      <h3 class="section-bar">Methods</h3>

      <div class="name-list">
      <a href="#M001340">transaction</a>&nbsp;&nbsp;
      </div>
    </div>

  </div>


    <!-- if includes -->

    <div id="section">





      


    <!-- if method_list -->
    <div id="methods">
      <h3 class="section-bar">Public Instance methods</h3>

      <div id="method-M001340" class="method-detail">
        <a name="M001340"></a>

        <div class="method-heading">
          <a href="#M001340" class="method-signature">
          <span class="method-name">transaction</span><span class="method-args">(&amp;block)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
See <a
href="ClassMethods.html">ActiveRecord::Transactions::ClassMethods</a> for
detailed documentation.
</p>
          <p><a class="source-toggle" href="#"
            onclick="toggleCode('M001340-source');return false;">[Source]</a></p>
          <div class="method-source-code" id="M001340-source">
<pre>
     <span class="ruby-comment cmt"># File vendor/rails/activerecord/lib/active_record/transactions.rb, line 125</span>
125:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">transaction</span>(<span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
126:         <span class="ruby-identifier">connection</span>.<span class="ruby-identifier">increment_open_transactions</span>
127: 
128:         <span class="ruby-keyword kw">begin</span>
129:           <span class="ruby-identifier">connection</span>.<span class="ruby-identifier">transaction</span>(<span class="ruby-identifier">connection</span>.<span class="ruby-identifier">open_transactions</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
130:         <span class="ruby-keyword kw">ensure</span>
131:           <span class="ruby-identifier">connection</span>.<span class="ruby-identifier">decrement_open_transactions</span>
132:         <span class="ruby-keyword kw">end</span>
133:       <span class="ruby-keyword kw">end</span>
</pre>
          </div>
        </div>
      </div>


    </div>


  </div>


<div id="validator-badges">
  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>

</body>
</html>